iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
JavaScript

不要再說你不會後端!30 天 Node.js 降維打擊指南 系列 第 14 篇

Day 14:第二階段總結與實作(任務管理 RESTful API)

  • 分享至 

  • xImage
  •  

恭喜來到第二階段的尾聲!今天我們要把 Express 框架的威力發揮出來,實作一個完整的 CRUD(新增、讀取、更新、刪除)系統。這個小專案將為你未來串接真實資料庫打下最堅實的基礎。

1. 規劃專案架構與 API 規格

在寫任何程式前,先定義好規格是後端工程師的好習慣。我們這次的資源名稱是 todos (待辦事項)。

API 規格表 (RESTful 標準):

  • GET /api/todos:取得所有任務。
  • POST /api/todos:新增一個任務。
  • PUT /api/todos/:id:更新特定任務的狀態(例如標記為已完成)。
  • DELETE /api/todos/:id:刪除特定任務。

資料夾結構:

express-api/
 ├── package.json
 ├── app.js             (主程式)
 └── routes/
      └── todos.js      (任務路由模組)

2. 實作路由邏輯 (routes/todos.js)

打開或建立 routes/todos.js,這是我們今天的主戰場:

import express from 'express';

const router = express.Router();

// 模擬資料庫:用一個陣列來暫存資料
let todos = [
    { id: '1700000000001', title: '學習 Express.js', completed: false },
    { id: '1700000000002', title: '挑戰 Day 14 實作', completed: true }
];

// 1. 取得所有任務 (Read)
router.get('/', (req, res) => {
    res.status(200).json({ success: true, data: todos });
});

// 2. 新增任務 (Create)
router.post('/', (req, res) => {
    const { title } = req.body;
    
    if (!title) {
        return res.status(400).json({ success: false, message: '必須提供任務標題 (title)' });
    }

    const newTodo = {
        id: Date.now().toString(), // 用時間戳記當作隨機 ID
        title: title,
        completed: false // 預設為未完成
    };

    todos.push(newTodo);
    res.status(201).json({ success: true, message: '任務新增成功', data: newTodo });
});

// 3. 更新任務狀態 (Update)
router.put('/:id', (req, res) => {
    const { id } = req.params;
    const { title, completed } = req.body;

    // 尋找陣列中有沒有這個 ID 的任務
    const todoIndex = todos.findIndex(todo => todo.id === id);

    if (todoIndex === -1) {
        return res.status(404).json({ success: false, message: '找不到該任務' });
    }

    // 更新資料 (如果有傳入新值就更新,否則保留原值)
    if (title !== undefined) todos[todoIndex].title = title;
    if (completed !== undefined) todos[todoIndex].completed = completed;

    res.status(200).json({ 
        success: true, 
        message: '任務更新成功', 
        data: todos[todoIndex] 
    });
});

// 4. 刪除任務 (Delete)
router.delete('/:id', (req, res) => {
    const { id } = req.params;
    
    // 過濾掉要刪除的 ID,重新賦值給 todos 陣列
    const initialLength = todos.length;
    todos = todos.filter(todo => todo.id !== id);

    if (todos.length === initialLength) {
        return res.status(404).json({ success: false, message: '找不到要刪除的任務' });
    }

    res.status(200).json({ success: true, message: '任務已刪除' });
});

export default router;

3. 組合主程式 (app.js)

最後,回到 app.js,把我們寫好的 Router 給掛載上去:

import express from 'express';
import todoRoutes from './routes/todos.js';

const app = express();
const PORT = 3000;

// 全域中介軟體:解析 JSON Request Body
app.use(express.json());

// 掛載路由
app.use('/api/todos', todoRoutes);

app.listen(PORT, () => {
    console.log(` To-Do API 伺服器啟動:http://localhost:${PORT}`);
    console.log(` 測試網址:http://localhost:${PORT}/api/todos`);
});

4. 終極測試

啟動伺服器 (node app.js),使用 Thunder Client 或 Postman 測試你的四大 API!
你現在已經具備了打造標準 Web API 的能力。不過每次伺服器重啟,陣列裡的資料就會消失,這就是為什麼我們接下來需要進入第三階段:資料庫的數據掌控!


上一篇
Day13
下一篇
#Day 15:資料庫雙雄對決(SQL vs NoSQL)
系列文
不要再說你不會後端!30 天 Node.js 降維打擊指南 共 16 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言